# -*- coding: utf-8 -*-
"""Main Controller"""
try:
    from mx import DateTime as mxdt
except ImportError:
    print "You need to install python-egenix-mx-base"
from datetime import datetime
import re
from tg import expose, flash, require, url, request, redirect,tmpl_context,validate, config
identity = request.environ.get('repoze.who.identity')
from pylons.i18n import ugettext as _, lazy_ugettext as l_
#from catwalk.tg2 import Catwalk
from repoze.what import predicates
from formencode import validators,Schema
from lifepyscle.lib.base import BaseController
from lifepyscle.lib.uploader import *
from lifepyscle.model import DBSession, metadata
from lifepyscle.controllers.error import ErrorController
from lifepyscle import model
from lifepyscle.model import *
from lifepyscle.controllers.secure import SecureController
from lifepyscle.widgets import event
from lifepyscle.widgets import reminder
from lifepyscle.widgets.fancybox import FancyBox
from lifepyscle.widgets.dummy import dummy_dynamicform
from lifepyscle.controllers.common import isValidEmail
cat="reminder" # added to every returned dict
reminder_form = reminder.reminder_form
import logging
log = logging.getLogger(__name__)

class ReminderController(BaseController):

    @expose('lifepyscle.templates.test_autoc')
    def index(self, **kw):
        tmpl_context.add_event_form = add_event.add_event_form
        tmpl_context.dummy_dynamicform = dummy_dynamicform
        form_id = "add_event_form"
        fieldset_id = "add_event_form_AddEventFieldSet" # nasty hack to get the tw generated fieldset id
        return dict(page="Add Event",cat=cat,form_id=form_id,fieldset_id=fieldset_id)

    @expose('json')
    def emails(self,**kw):
        print kw
        return [False]

    @expose('lifepyscle.templates.test_reminder')
    def test(self,**kw):
        tmpl_context.fb = FancyBox()
        return dict(cat=cat,page="Test Reminder")

    # TODO: Refactor this to somewhere where it is reusable
    @expose('lifepyscle.templates.error_iframe')
    def error_iframe(self,title,message,**kw):
        return dict(title=title,message=message)

    @expose('lifepyscle.templates.reminder_iframe')
    def iframe(self,event_id=None,**kw):
        """ need to pass event data through to the iframe """
        if not event_id:
            t = 'Ooops, no event specified'
            m = 'An error occurred. You wanted to add a reminder to an event but did not specify which event'
            redirect(url('/reminder/error_iframe?title=%s&message=%s'%(t,m)))
        else:
            try:
                E = DBSession.query(Event).filter(Event.event_id=='%s'%event_id).one()
            except:
                t = 'Ooops, bad event id passed'
                m = 'An error occurred. You wanted to add a reminder to an event with id %s but that event was not found'%event_id
                redirect(url('/reminder/error_iframe?title=%s&message=%s'%(t,m)))
            else:
                users  = DBSession.query(User).all()
                user_options = []
                #for u in users:
                #    if u.user_name != "manager" and u.user_name != "editor":
                #        user_options.append((u.user_id,u.display_name))
                tmpl_context.reminder_form = reminder_form
                return dict(cat=cat,user_options=user_options,event=E)

    @expose('json')
    #@validate(form=reminder_form,error_handler=iframe) # validating was done by jscript already but we can revalidate here
    def add(self,**kw):
        """ Steps:
        * get the Event from the event_id sent to this controller
        * get the startDate from the event
        * count back x = kw['trigger'] days from startDate
        * check if x is before the current date (no point in reminder)
        * save reminder to dbase
        * pass control to cronjob
        """
        this_user = request.environ.get('repoze.who.identity')['user']
        trigger = int(kw['trigger']) # should already be an int(?)
        message = kw['message']
        users_involved = request.params.getall('users_involved[]')
        if not users_involved: # add the current users id if nothing added.
            users_involved = [this_user.user_id]
        event_id = kw['event_id']
        # Loop through the users and extract and verify the ints (user_id). For anything that is not an int
        # verify that it is an email address
        by_email,bad_emails = [],[]
        existing_users = [] # stores lifepyscle users who should be associated with this reminder
        for u in users_involved:
            try:
                u_as_int = int(u)
            except ValueError: # obviously not an int
                if isValidEmail(u):
                    by_email.append(u)
                else:
                    bad_emails.append(u)
            else:
                try:
                    existing_user = DBSession.query(User).filter(User.user_id==u).one()
                except:
                    log.warning("Did not find user with user_id %d in the dbase"%u)
                else:
                    log.info("Found existing user %s with user_id %d"%(existing_user.user_name,existing_user.user_id))
                    existing_users.append(existing_user)
        if this_user not in existing_users:
            log.info("Adding currently logged in user %s (who performed current add reminder action) to reminder users"%this_user.user_name)
            existing_users.append(this_user)
        else:
            log.info("Current user %s was already added to the reminder's associated users - not adding"%this_user.user_name)
        # see if we already know the non_user_emails
        existing_emails = []
        if len(by_email):
            for email in by_email:
                try:
                    existing_nue = DBSession.query(NUE).filter(NUE.email==email).one()
                except Exception,e:
                    log.info("Did not find existing email %s in the database. Adding this email as NUE class now..."%email)
                    new_nue = NUE(email)
                    existing_emails.append(new_nue)
                else:
                    log.info("Found NUE class email %s in the database"%email)
                    existing_emails.append(existing_nue)
        try:
            E = DBSession.query(Event).filter(Event.event_id==event_id).one()
        except:
            add_status = 'fail'
            return dict(cat=cat,kw=kw,add_status=add_status)
        else:
            # See if the reminder takes place before now() - if so do not enter it
            R = Reminder()
            E.reminders.append(R)
            DBSession.flush()
            
            R.trigger = trigger
            R.message = message
            for x in existing_emails:
                R.non_user_emails.append(x)
            add_status = 'ok'
            return dict(cat=cat,kw=kw,add_status=add_status)

    @expose('json')
    def delete(self,reminder_id=None,**kw):
        if not reminder_id:
            return dict(delete_status='fail',msg='No reminder id sent')
        else:
            try:
                R = DBSession.query(Reminder).filter(Reminder.reminder_id==reminder_id).one()
            except:
                return dict(delete_status='fail',msg='Reminder with reminder_id %s not found'%reminder_id)
            else:
                DBSession.delete(R)
                return dict(delete_status='ok',msg='Successfully deleted that reminder')

    @expose('json')
    def refresh(self,event_id=None,**kw):
        if not event_id:
            return dict(refresh_status=1,code=u'no_event_id',msg=u'No event id was provided')
        order_by = 'a'
        if kw.has_key('order'):
            if kw['order'] == 'd': order_by = 'd'
            elif kw['order'] == 'a': order_by = 'a'
            else: order_by = 'a'
        try:
            if order_by=='d':
                reminders = DBSession.query(Reminder).filter(Reminder.event_id==event_id).order_by(Reminder.trigger.desc())
            else:
                reminders = DBSession.query(Reminder).filter(Reminder.event_id==event_id).order_by(Reminder.trigger.asc())
        except:
            return dict(refresh_status=1,code=u'non_existent_event',msg=u'No event exists with id %s'%event_id)
        else:
            reminders = reminders.all()
            rlist = []
            for x in reminders: # this loop needed in order to inject the actual trigger date (model doesn't store this - it stores int(trigger))
                tmp = {}
                tmp['message'] = x.message
                tmp['triggerDate'] = datetime.strftime(x.triggerDate,"%Y-%m-%d")
                tmp['status'] = x.status
                tmp['reminder_id'] = x.reminder_id
                tmp['trigger'] = x.trigger
                # now check what we are actually requested to display - all reminders, or the one later than today
                if kw.has_key('old'):
                    if kw['old'] == '0': # reminders earlier than today
                        today = datetime.now()
                        if x.triggerDate >= today:
                            rlist.append(tmp)
                    elif kw['old'] == '1':
                        rlist.append(tmp)
                else:
                    rlist.append(tmp)
            return dict(refresh_status=0,code=u'ok',reminders=rlist,msg='Retrieved %d reminders for event with id %s'%(len(reminders),event_id))

